import 'package:hi_net/core/dio_adapter.dart';
import 'package:hi_net/core/hi_error.dart';
import 'package:hi_net/core/hi_net_adapter.dart';
import 'package:hi_net/request/h_base_request.dart';

///1.支持网络库插拔设计，且不干扰业务层
///2.基于配置请求请求，简洁易用
///3.Adapter设计，扩展性强
///4.统一异常和返回处理
class HiNet {
  HiNet._();

  static HiNet _instance;

  static HiNet getInstance() {
    if (_instance == null) {
      _instance = HiNet._();
    }
    return _instance;
  }

  Future fire(HBaseRequest request) async {
    HiNetResponse response;
    var error;
    try {
      response = await send(request);
    } on HiNetError catch (e) {
      error = e;
      response = e.data;
      // hyLog(e.message, StackTrace.current);
    } catch (e) {
      // 其它的异常
      error = e;
      // hyLog(e, StackTrace.current);
    }

    if (response == null) {
      // hyLog('response为空:$error', StackTrace.current);
      print('response为空:$error');
    } else {
      var result = response.data;
      // 解析状态码
      var status = response.statusCode;
      switch (status) {
        case 200:
          return result;
          break;
        case 401: //登录
          throw NeedLogin();
          break;
        case 403: //鉴权
          throw NeedAuth(result.toString(), data: result);
          break;
        default: //状态码不是200都会走到这里来 这也是为什么会抛错误
          // hyLog('请求状态码不在范围内', StackTrace.current);
          print('请求状态码不在范围内');
          throw HiNetError(status, result.toString(), data: result);
      }
    }
  }

  Future<dynamic> send<T>(HBaseRequest request) async {
    // 这里用来切换底层网络库

    // 方式一： 这里写的数据
    // return Future.value({
    //   "data": {"code": 0, "message": 'success'},
    //   "statusCode": 200
    // });

    // 方式二： 这是就是往外面发送请求数据 --可以写假数据--这里是用的mock的假数据===》实现mock三方库一样的道理
    // HiNetAdapter adapter = MockAdapter();
    // return adapter.send(request);
    // 方式三：使用http
    // HiNetAdapter adapter = HttpAdapter();
    // return adapter.send(request);

    // // 方式四：使用dio
    HiNetAdapter adapter = DioAdapter();
    return adapter.send(request);
  }
}
